﻿using System.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace Marbles.Data
{
    public class DataSource : BaseDataSource, IDataSource
    {
        // Fields
        private IDataSource _dbc;

        // Methods
        public DataSource()
        {
            this._dbc = null;
            this._dbc = Create();

            //string provider = WebConfigurationManager.ConnectionStrings["Default"].ProviderName.ToLower();
            //switch (provider.ToLower())
            //{
            //    case "sqlclient": this._dbc = new SqlDataSourceProvider("Default"); break;
            //    case "oracleclient": this._dbc = new OracleDataSourceProvider("Default"); break;
            //    case "oledbclient": this._dbc = new OleDbDataSourceProvider("Default"); break;
            //    case "odbcclient": this._dbc = new OdbcDataSourceProvider("Default"); break;
            //    case "mysqlclient": this._dbc = new MySqlDataSourceProvider("Default"); break;
            //    case "npgsql": this._dbc = new PostgreSQLDataSourceProvider("Default"); break;
            //    case "postgresqlclient": this._dbc = new PostgreSQLDataSourceProvider("Default"); break;
            //    default: throw new InvalidExpressionException("Unknown Database Provider.");
            //}

        }

        public DataSource(string ParameterName)
        {
            this._dbc = null;
            this._dbc = Create(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[ParameterName]);

            //string provider = WebConfigurationManager.ConnectionStrings[ParameterName].ProviderName.ToLower();
            //switch (provider.ToLower())
            //{
            //    case "sqlclient": this._dbc = new SqlDataSourceProvider(ParameterName); break;
            //    case "oracleclient": this._dbc = new OracleDataSourceProvider(ParameterName); break;
            //    case "oledbclient": this._dbc = new OleDbDataSourceProvider(ParameterName); break;
            //    case "odbcclient": this._dbc = new OdbcDataSourceProvider(ParameterName); break;
            //    case "mysqlclient": this._dbc = new MySqlDataSourceProvider(ParameterName); break;
            //    case "npgsql": this._dbc = new PostgreSQLDataSourceProvider("Database"); break;
            //    case "postgresqlclient": this._dbc = new PostgreSQLDataSourceProvider("Database"); break;
            //    default: throw new InvalidExpressionException("Unknown Database Provider.");
            //}

        }

        public void Close()
        {
            this._dbc.Close();
        }

        public int ExecuteCommand(DataSourceCommand Command)
        {
            return this._dbc.ExecuteCommand(Command);
        }

        public DataSet FetchDataSet(DataSourceCommand Command)
        {
            return this._dbc.FetchDataSet(Command);
        }

        public DataTable FetchDataTable(DataSourceCommand Command)
        {
            return this._dbc.FetchDataTable(Command);
        }

        public IDataReader FetchReader(DataSourceCommand Command)
        {
            return this._dbc.FetchReader(Command);
        }

        public bool IsConnected()
        {
            return this._dbc.IsConnected();
        }

        public void Open()
        {
            this._dbc.Open();
        }

        public string Provider
        {
            get
            {
                return this._dbc.Provider;
            }
        }

        public string[] ListDatabases()
        {
            return this._dbc.ListDatabases();
        }

        public DataSourceTable[] ListTables(string Database)
        {
            return this._dbc.ListTables(Database);
        }

        public DataSourceTableDefinition GetTableDefinition(DataSourceTable Table)
        {
            return this._dbc.GetTableDefinition(Table);
        }

        public static IDataSource Create()
        {
            return Create("Default");
        }

        public static IDataSource cREATE(string typename, string connectionString)
        {
            switch (typename)
            {
                case "Marbles.Data.SqlDataSourceProvider": return new SqlDataSourceProvider(connectionString);
                case "Marbles.Data.OracleDataSourceProvider": return new OracleDataSourceProvider(connectionString);
                case "Marbles.Data.OleDbDataSourceProvider": return new OleDbDataSourceProvider(connectionString);
                case "Marbles.Data.OdbcDataSourceProvider": return new OdbcDataSourceProvider(connectionString);
                case "Marbles.Data.MySqlDataSourceProvider": return new MySqlDataSourceProvider(connectionString);
                case "Marbles.Data.PostgreSQLDataSourceProvider": return new PostgreSQLDataSourceProvider(connectionString); 
                default: throw new InvalidExpressionException("Unknown Database Provider.");
            }

        }

        public static IDataSource Create(string ParameterName)
        {
            ConnectionStringSettings config = System.Web.Configuration.WebConfigurationManager.ConnectionStrings[ParameterName];
            return Create(config);
        }

        public static IDataSource Create(ConnectionStringSettings ConnectionSettings)
        {
            Type t = Type.GetType(ConnectionSettings.ProviderName);
            IDataSource cntlr = Activator.CreateInstance(t, new object[] { ConnectionSettings.ConnectionString }) as IDataSource;
            return cntlr;
        }

    }

}
